package main

import (
	"fmt"
	"net"
	"strings"
)

// user 结构体
type User struct {
	Name string
	Addr string

	// 消息chan
	Message chan string
	// 连接
	conn net.Conn
	// 当前用户所使用服务器
	server *Server
}

func (u *User) SendMsg(msg string) {
	_, err := u.conn.Write([]byte(msg + "\n"))
	if err != nil {
		fmt.Printf("向客户发送消息失败: %v\n", err)
	}
}

// 监听消息channel，有消息时发送给客户端
func (u *User) ListenMessage() {
	for {
		msg := <-u.Message
		u.SendMsg(msg)
	}
}

// 用户上线业务处理
func (u *User) Online() {
	// 当前用户加入在线列表
	u.server.mapLock.Lock()
	u.server.OnlineMap[u.Name] = u
	u.server.mapLock.Unlock()

	// 发送上线广播
	u.server.BroadCast(u, "上线了")
}

// 用户下线业务处理
func (u *User) Offline() {
	// 从在线列表中删除当前用户
	u.server.mapLock.Lock()
	delete(u.server.OnlineMap, u.Name)
	u.server.mapLock.Unlock()

	// 发送下线广播
	u.server.BroadCast(u, "下线了")
}

// 查询在线用户
func (u *User) QueryUser() {
	users := make([]string, 0)
	u.server.mapLock.Lock()
	for name := range u.server.OnlineMap {
		users = append(users, name)
	}
	u.server.mapLock.Unlock()

	u.SendMsg(fmt.Sprintf(">>>当前在线用户: %s", strings.Join(users, ", ")))
}

// 用户修改用户名
func (u *User) Rename(msg string) {
	msgSplit := strings.SplitN(strings.TrimSpace(msg), " ", 2)
	if len(msgSplit) < 2 {
		u.SendMsg("请提供用户名")
		return
	}

	name := strings.TrimSpace(msgSplit[1])
	if name == "" {
		u.SendMsg("请提供用户名")
		return
	}
	if _, ok := u.server.OnlineMap[name]; ok {
		u.SendMsg("该用户名已经被使用，请使用其他用户名")
		return
	}
	u.server.mapLock.Lock()
	if _, ok := u.server.OnlineMap[u.Name]; ok {
		delete(u.server.OnlineMap, u.Name)
	}
	u.server.OnlineMap[name] = u
	u.server.mapLock.Unlock()
	u.Name = name
	u.server.BroadCast(u, fmt.Sprintf("用户名改为了: %s", u.Name))
}

// 私聊消息处理
func (u *User) PrivateChat(msg string) {
	msgSplit := strings.SplitN(msg, " ", 2)
	if len(msgSplit) < 2 {
		return
	}
	name := strings.SplitN(msgSplit[0], "@", 2)[1]
	user, ok := u.server.OnlineMap[name]
	if !ok {
		u.SendMsg("请选择正确的聊天对象")
		u.QueryUser()
		return
	}
	content := fmt.Sprintf("%s: %s", u.Name, msgSplit[1])
	user.SendMsg(content)
}

// 发送消息处理
func (u *User) DoMessage(msg string) {
	if len(msg) == 0 {
		return
	}
	// 在线用户查询
	if msg == "who" {
		u.QueryUser()
		return
	}
	// 修改用户名
	if msg == "rename" || strings.HasPrefix(msg, "rename ") {
		u.Rename(msg)
		return
	}
	// 私聊消息
	if strings.HasPrefix(msg, "@") {
		u.PrivateChat(msg)
		return
	}
	// 发送广播消息
	u.server.BroadCast(u, msg)
}

// 创建user接口
func NewUser(conn net.Conn, server *Server) *User {
	addr := conn.RemoteAddr().String()
	user := &User{
		Name:    addr,
		Addr:    addr,
		Message: make(chan string),
		conn:    conn,
		server:  server,
	}
	// 当前用户监听消息
	go user.ListenMessage()

	return user
}
